package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.zzyl.constant.CacheConstants;
import com.zzyl.dto.AlertDataPageQueryDto;
import com.zzyl.entity.AlertData;
import com.zzyl.entity.AlertRule;
import com.zzyl.mapper.*;
import com.zzyl.service.AlertDataService;
import com.zzyl.service.RedisService;
import com.zzyl.utils.ObjectUtil;
import com.zzyl.vo.AlertDataVo;
import com.zzyl.vo.DeviceDataVo;
import com.zzyl.vo.DeviceVo;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description AlertDataServiceImpl
 * @Author Hua Caoxing
 * @Data 2025-09-15
 */
@Service
public class AlertDataServiceImpl implements AlertDataService {

    @Autowired
    private AlertDataMapper alertDataMapper;

    /**
     * 分页查询
     *
     * @param alertDataPageQueryDto
     * @return
     */
    @Override
    public List<AlertDataVo> pageQuery(AlertDataPageQueryDto alertDataPageQueryDto) {

        return List.of();
    }

    /**
     * 报警规则合并
     *
     * @param
     * @return
     */
    @Override
    public List<AlertRule> normalize(String iotId, String productKey, List<AlertRule> alertRules) {
        return alertRules.stream().
                filter(alertRule -> alertRule.getProductKey().equals(productKey) && (alertRule.getIotId().equals(iotId) || alertRule.getIotId().equals("-1")))
                .collect(Collectors.toList());
    }

    /**
     * 报警处理
     *
     * @param deviceDataVo
     * @param alertRules
     * @return
     */
    @Autowired
    private RedisService redisService;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Override
    public void process(DeviceDataVo deviceDataVo, List<AlertRule> alertRules) {

        List<AlertData> alertDatas = new ArrayList<>();
        // 1. 遍历报警规则
        for (AlertRule alertRule : alertRules) {
            String iotId = alertRule.getIotId();
            String functionId = alertRule.getFunctionId();
            if (!((deviceDataVo.getIotId().equals(iotId)||iotId.equals("-1"))&&deviceDataVo.getFunctionId().equals(functionId))){
                continue;
            }

            // 获取报警 生效开始结束时间
            String[] effectivePeriod = alertRule.getAlertEffectivePeriod().split("~");
            // 修改开始：处理只有时间部分的字符串
            LocalDate today = LocalDate.now();
            LocalTime startTime = LocalTime.parse(effectivePeriod[0]);
            LocalTime endTime = LocalTime.parse(effectivePeriod[1]);
            LocalDateTime start = LocalDateTime.of(today, startTime);
             LocalDateTime end = LocalDateTime.of(today, endTime);
            // 2. 报警生效时段判断
            if (!(deviceDataVo.getAlarmTime().isAfter(start) && deviceDataVo.getAlarmTime().isBefore(end))) {
                continue;
            }
            // 检验数据是否达到 阈值
            if ((alertRule.getOperator().equals(">="))) {
                if (!(Float.valueOf(deviceDataVo.getDataValue()) >= alertRule.getValue())) {
                    // todo 删除redis报警数
                    // iotId 做大key functionid 小key
                    redisService.delete(iotId, functionId, CacheConstants.ALERT_COUNT_CACHE_KEY);
                    continue;
                }
            } else if ((alertRule.getOperator().equals("<"))) {
                if (!(Float.valueOf(deviceDataVo.getDataValue())< alertRule.getValue())) {
                    // todo 删除redis报警数
                    // iotId 做大key functionid 小key
                    redisService.delete(iotId, functionId, CacheConstants.ALERT_COUNT_CACHE_KEY);
                    continue;
                }
            }
            // todo 判断沉默周期 设计 过期时间
            String silentPeriod = redisService.hasKey(CacheConstants.ALERT_SILENT_PERIOD, iotId, functionId);
            if (silentPeriod != null) {
                continue;
            }

            // 判断当前报警的次数
            // todo 报警次数缓存 设计
            String result = redisService.hasKey(CacheConstants.ALERT_COUNT_CACHE_KEY, iotId, functionId);
            Integer count = 0;
            if (result != null) {
                count = Integer.parseInt(result);
            }
            count++;
            // 报警次数 是否等于持续周期
            if (!count.equals(alertRule.getDuration())) {
                // todo 报警次数缓存 设计 过期时间
                redisService.setCount(CacheConstants.ALERT_COUNT_CACHE_KEY, iotId, functionId, count);
                continue;
            }
            // 删除报警数
            redisService.delete(iotId, functionId, CacheConstants.ALERT_COUNT_CACHE_KEY);
            // 添加沉默周期到redis
            //设置静默周期
            redisService.setSilentPeriod(iotId, functionId, alertRule.getAlertSilentPeriod());
            // 是否是老人异常数据
            if (deviceDataVo.getPhysicalLocationType().equals(-1) || deviceDataVo.getPhysicalLocationType().equals(2)) {
                // 是老人异常设备
                List<String> nursingIds = null;
                // 是否是固定设备
                if (deviceDataVo.getLocationType().equals(2)) {
                    // 是固定设备
                    nursingIds = deviceMapper.selectNursingId(deviceDataVo.getIotId());
                } else {
                    // 否
                    // 获取老人id
                    nursingIds = deviceMapper.selectNursingIdWithElder(deviceDataVo.getIotId());
                }
                if (ObjectUtil.isEmpty(nursingIds)) {
                    continue;
                }
                // 员工id分别存入到数据中
                for (String nursingId : nursingIds) {
                    AlertData alertData = BeanUtil.toBean(deviceDataVo,AlertData.class);
                    alertData.setDeviceName(alertRule.getDeviceName());
                    alertData.setProductKey(alertRule.getProductKey());
                    alertData.setProductName(alertRule.getProductName());
                    alertData.setAlertRuleId(alertRule.getId());
                    alertData.setType(alertRule.getAlertDataType());
                    alertData.setAlertReason(alertRule.getFunctionName() + alertRule.getOperator() + alertRule.getValue().toString()+","+alertRule.getDuration()+","+alertRule.getAlertEffectivePeriod());
                    alertData.setStatus(0);
                    alertData.setUserId(Long.valueOf(nursingId));
                    alertDatas.add(alertData);
                }
            } else {
                // 不是老人异常设备
                // 查询维修工
                List<Long> maintenanceIds = sysUserRoleMapper.getMaintenanceId();
                if (ObjectUtil.isEmpty(maintenanceIds)) {
                    continue;
                }
                // 员工id分别存入到数据中
                for (Long maintenanceId : maintenanceIds) {
                    AlertData alertData = BeanUtil.toBean(deviceDataVo,AlertData.class);
                    alertData.setDeviceName(alertRule.getDeviceName());
                    alertData.setProductKey(alertRule.getProductKey());
                    alertData.setProductName(alertRule.getProductName());
                    alertData.setAlertRuleId(alertRule.getId());
                    alertData.setType(alertRule.getAlertDataType());
                    alertData.setAlertReason(alertRule.getFunctionName() + alertRule.getOperator() + alertRule.getValue().toString()+","+alertRule.getDuration()+","+alertRule.getAlertEffectivePeriod());
                    alertData.setStatus(0);
                    alertData.setUserId(maintenanceId);
                    alertDatas.add(alertData);
                }
            }
            // 3. 报警数据添加到数据库
            if (ObjectUtil.isEmpty(alertDatas)) {
                continue;
            }
            alertDataMapper.batchInsert(alertDatas);
        }

    }


}
